package com.atguigu.paymentdemo.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayConfig;
import com.alipay.api.AlipayConstants;
import com.alipay.api.internal.util.AlipaySignature;
import com.atguigu.paymentdemo.config.AlipayClientConfig;
import com.atguigu.paymentdemo.entity.OrderInfo;
import com.atguigu.paymentdemo.service.AliPayService;
import com.atguigu.paymentdemo.service.OrderInfoService;
import com.atguigu.paymentdemo.util.HttpUtils;
import com.atguigu.paymentdemo.util.WechatPay2ValidatorForRequest;
import com.atguigu.paymentdemo.vo.R;
import com.google.gson.Gson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ForkJoinPool;

/**
 * @author longge
 * @Title:
 * @Description:
 * @date 2023/2/13 22:33
 */
@RestController
@RequestMapping("/api/ali-pay")
@Api(tags = "网站 支付宝 支付")
@Slf4j
public class AliPayController {

    @Autowired
    private AliPayService aliPayService;
    @Autowired
    private AlipayClientConfig alipayClientConfig;

    @Autowired
    private OrderInfoService orderInfoService;

    @ApiOperation("统一下单并支付")
    @PostMapping("/trade/page/pay/{productId}")
    public R tradePagePay(@PathVariable() Long productId) {
        log.info("统一下单并支付页面接口的调用");

        //调用支付宝统一下单，返回一个from表单字符串
        String formStr = aliPayService.tradeCreate(productId);
        return R.ok().data("formStr", formStr);
    }

    @ApiOperation("回调地址")
    @PostMapping("/trade/notify")
    public String nativeNotify(@RequestParam Map<String,String> params){
        log.info("支付宝支付通知正在执行");
        log.info("支付通知参数 ===> {}",params);

        String result = "fail";

        try {
            //调用SDK验证签名
            boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayClientConfig.getAlipayPublicKey(),
                    AlipayConstants.CHARSET_UTF8, AlipayConstants.SIGN_TYPE_RSA2);
            if(!signVerified){
                log.info("支付成功，异步通知验签失败");
            }

            //1. 商家需要验证该通知数据中的 out_trade_no 是否为商家系统中创建的订单号。
            String outTradeNo = params.get("out_trade_no");
            OrderInfo orderByOrder = orderInfoService.getOrderByOrderNo(outTradeNo);
            if(Objects.isNull(orderByOrder)){
                log.error("订单不存在");
                return result;
            }

            //2. 判断 total_amount 是否确实为该订单的实际金额（即商家订单创建时的金额）。
            String totalAmount = params.get("total_amount");
            int totalAmountInt = new BigDecimal(totalAmount).multiply(new BigDecimal("100")).intValue();
            if(!orderByOrder.getTotalFee().equals(totalAmountInt)){
                log.error("订单金额不对");
                return result;
            }

            //3. 校验通知中的 seller_id（或者 seller_email) 是否为 out_trade_no 这笔单据的对应的操作方（有的时候，一个商家可能有多个 seller_id/seller_email）。
            String sellerId = params.get("seller_id");
            if(!alipayClientConfig.getSellerId().equals(sellerId)){
                log.error("卖家支付宝账号ID不对应");
                return result;
            }

            //4. 验证 app_id 是否为该商家本身。
            String appId = params.get("app_id");
            if(!alipayClientConfig.getAppId().equals(appId)){
                log.error("appId 对应不上");
                return result;
            }

            String tradeStatus = params.get("trade_status");
            if (!"TRADE_SUCCESS".equals(tradeStatus)){
                log.info("支付失败");
                return result;
            }

            aliPayService.processOrder(params);

            log.info("支付成功，异步通知验签成功");
            result = "success";
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

        return result;
    }
}
